package com.wj.service.impl;

import com.wj.domain.entity.BookCacheEntity;
import com.wj.domain.vo.BookCacheVO;
import com.wj.domain.vo.BookVO;
import com.wj.domain.vo.ChapterContentVO;
import com.wj.domain.vo.ChapterVO;
import com.wj.infrastructure.mapper.BookCacheMapper;
import com.wj.infrastructure.mapper.ChapterMapper;
import com.wj.infrastructure.repository.BookCacheRepository;
import com.wj.service.BookCacheService;
import com.wj.service.BookService;
import com.wj.service.ChapterContentService;
import com.wj.tool.common.exception.SelfException;
import com.wj.tool.common.utils.CollectionUtils;
import com.wj.tool.common.utils.UuidUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class BookCacheServiceImpl implements BookCacheService {

    @Resource
    private BookCacheRepository bookCacheRepository;

    @Resource
    private ChapterMapper chapterMapper;

    @Resource
    private ChapterContentService chapterContentService;

    @Resource
    private BookService bookService;

    @Value("${file.absopath_pre}")
    private String file_absopath_pre;

    @Value("${file.realpath_pre}")
    private String file_realpath_pre;

    @Resource
    private BookCacheMapper bookCacheMapper;

    @Override
    public BookCacheVO getCacheByBookId(Long bookId) {
        BookCacheEntity bookCacheEntity = bookCacheRepository.findByBookId(bookId);
        if (bookCacheEntity == null){
            throw new SelfException("该书籍未缓存");
        }
        BookCacheVO bookCacheVO = new BookCacheVO();
        bookCacheVO.setBookName(bookCacheEntity.getBookName());
        bookCacheVO.setAbsolutePath(bookCacheEntity.getAbsolutePath());
        bookCacheVO.setRelativePath(bookCacheEntity.getRelativePath());
        return bookCacheVO;
    }

    @Override
    @Async
    @Transactional(rollbackFor = Exception.class)
    public void createBookFile(Long bookId, String bookName) {
        FileOutputStream outStr = null;
        BufferedOutputStream buff = null;
        String oldPath = "";
        try {
            //设置响应头，对文件进行url编码
//            String bookNameStr = URLEncoder.encode(bookName, "UTF-8");

            //查看书籍缓存
            BookCacheEntity bookCacheEntity = bookCacheRepository.findByBookId(bookId);

            SimpleDateFormat sdf = new SimpleDateFormat("YYYYMMddHHmmss");
            String newFileName =  sdf.format(new Date()) + ".txt";
            //存储路径
            String fileAbsoPath = file_absopath_pre + bookName + "/" + bookName + newFileName;

            String fileRealpath = file_realpath_pre + bookName + "/" + bookName + newFileName;
            File newFile = new File(fileAbsoPath);
            // 检测是否存在目录
            if (!newFile.getParentFile().exists()){
                newFile.getParentFile().mkdirs();
            }


            outStr = new FileOutputStream(new File(fileAbsoPath));

            buff = new BufferedOutputStream(outStr);
            List<ChapterVO> chapterList = new ArrayList<>();
            if (bookCacheEntity == null){
                bookCacheEntity = new BookCacheEntity();
                bookCacheEntity.setId(UuidUtils.createId());
                bookCacheEntity.setBookId(bookId);
                bookCacheEntity.setBookName(bookName);
                chapterList = chapterMapper.queryListByBookId(bookId);
            } else {
                oldPath = bookCacheEntity.getAbsolutePath();
                // 老文件复制
                File oldFile = new File(oldPath);
                FileInputStream fis = new FileInputStream(oldFile);
                BufferedInputStream bis = new BufferedInputStream(fis);
                copyFile(bis, buff);

                chapterList = chapterMapper.queryListByBookIdAndFromChapterId(bookId, bookCacheEntity.getChapterId());
                oldFile.delete();
            }
            bookCacheEntity.setAbsolutePath(fileAbsoPath);
            bookCacheEntity.setRelativePath(fileRealpath);

            int i = 0;
            double k = 0.0;
            int size = chapterList.size();
            SimpleDateFormat sd = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
            if (CollectionUtils.isNotEmpty(chapterList)){
                log.info("开始缓存："+bookName+",一共"+chapterList.size()+"章，当前时间"+sd.format(new Date()));
                for (ChapterVO chapterVO:chapterList){
                    Long contentId = chapterVO.getContentId();
                    ChapterContentVO chapterContent=chapterContentService.getById(contentId);
                    String content = chapterContent.getContent();
                    String chapterName = chapterVO.getChapterTitle();
                    buff.write(chapterName.getBytes(StandardCharsets.UTF_8));
                    buff.write("\n".getBytes(StandardCharsets.UTF_8));
                    content = content
//                            .replaceAll(Constants.CONTENT_AD_PATTERN, "")
                            .replaceAll("<br\\s*/*>", "\r\n")
                            .replaceAll("&nbsp;", " ")
                            .replaceAll("<a[^>]*>", "")
                            .replaceAll("</a>", "")
                            .replaceAll("<div[^>]*>", "")
                            .replaceAll("</div>", "")
                            .replaceAll("<p[^>]*>[^<]*<a[^>]*>[^<]*</a>\\s*</p>", "")
                            .replaceAll("<p[^>]*>", "")
                            .replaceAll("</p>", "\r\n");
                    buff.write(content.getBytes(StandardCharsets.UTF_8));
                    buff.write("\r\n".getBytes(StandardCharsets.UTF_8));
                    buff.write("\r\n".getBytes(StandardCharsets.UTF_8));
                    buff.flush();

                    double thisChapterSortD = Math.ceil(size * k);
                    int thisChapterSort = (int) thisChapterSortD;
                    if (i == thisChapterSort){
                        int process = (int) (k * 100);
                        log.info(bookName+"缓存进度："+process+"%");
                        k+=0.1;
                    }
                    i++;
                }
            }

            if (CollectionUtils.isNotEmpty(chapterList)){
                int maxIndex = chapterList.size() -1;
                Long maxChapterId = chapterList.get(maxIndex).getId();
                String maxChapterTitle = chapterList.get(maxIndex).getChapterTitle();
                bookCacheEntity.setChapterId(maxChapterId);
                bookCacheEntity.setChapterTitle(maxChapterTitle);
            }
            bookCacheEntity.setCacheTime(new Date());;
            bookCacheRepository.save(bookCacheEntity);

            buff.close();
            outStr.close();

            log.info(bookName+"缓存完成，当前时间："+sd.format(new Date()));
        } catch (Exception e){
            throw new SelfException("生成txt出错:"+e);
        }

    }

    @Override
    public List<BookVO> getCacheBookList() {
        List<BookVO> cacheBookList = bookCacheMapper.getCacheBookList();
        return cacheBookList;
    }

    public void copyFile(InputStream input, OutputStream output) throws IOException {
        byte aByte;
        while((aByte = (byte)input.read()) != -1) {
            output.write(aByte);
        }
    }

    public static void main(String[] args) {
        int size = 201;
        double x = size*0.1;
        int as = (int) Math.ceil(x);
        System.out.println(as);
    }
}